package de.hdu.pms.dao;

import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

import org.apache.log4j.Logger;
import org.junit.Test;

import de.hdu.pms.model.Arbeitstag;
import de.hdu.pms.model.Basis;
import de.hdu.pms.model.Mitarbeiter;
import de.hdu.pms.model.Pausen;

public class PausenDaoTest extends AbstractDataAccessTest {

	public static Logger Log = Logger.getLogger(PausenDaoTest.class);

	private MitarbeiterDao mitarbeiterDao = null;
	private ArbeitstagDao arbeitstagDao = null;
	private BasisDao basisDao = null;
	private PausenDao pausenDao = null;

	public void setMitarbeiterDao(MitarbeiterDao mitarbeiterDao) {
		this.mitarbeiterDao = mitarbeiterDao;
	}

	public void setArbeitstagDao(ArbeitstagDao arbeitstagDao) {
		this.arbeitstagDao = arbeitstagDao;
	}

	public void setBasisDao(BasisDao basisDao) {
		this.basisDao = basisDao;
	}

	public void setPausenDao(PausenDao pausenDao) {
		this.pausenDao = pausenDao;
	}

	public static void setLog(Logger log) {
		Log = log;
	}

	@Test
	public void testFindById() {
		Log.info("UnitTest - Pausen - FindById");
		this.makePause(false);
		List<Pausen> allePausen = pausenDao.findAll();
		for (Pausen p : allePausen) {
			Pausen found = pausenDao.findById(p.getId());
			assertEquals(p.getId(), found.getId());
			assertEquals(p.getPause_start(), found.getPause_start());
			assertEquals(p.getPause_stop(), found.getPause_stop());
		}
		this.destroyPause();
	}

	@Test
	public void testFindAll() {
		Log.info("UnitTest - Pausen - FindAll");
		this.testFindById();
	}

	@SuppressWarnings("deprecation")
	@Test
	public void testSave() {
		Log.info("UnitTest - Pausen - Save");
		this.makePause(false);
		int rows = countRowsInTable("pausen");
		assertEquals("Es darf nur ein Datensatz vorhanden sein", 1, rows);
		this.destroyPause();
	}

	@Test
	public void testDelete() {
		Log.info("UnitTest - Pausen - Delete");
		Pausen pause = this.makePause(false);
		try {
			pausenDao.delete(pause);
		} catch (Exception e) {
			Log.info("Exception: " + e.getCause());
		}
		List<Pausen> alle = pausenDao.findAll();
		assertEquals(0, alle.size());
		this.destroyPause();
	}

	@Test
	public void testFindNichtBeendet() {
		Log.info("UnitTest - Pausen - FindNichtBeendet");
		Pausen pause = this.makePause(true);
		Pausen nichtBeendet = pausenDao.findNichtBeendet(pause.getArbeitstag()
				.getId());
		assertEquals(pause.getId(), nichtBeendet.getId());
		this.destroyPause();
	}

	@Test
	public void testFindByAtag() {
		Log.info("UnitTest - Pausen - FindByAtag");
		Pausen pause = this.makePause(false);
		List<Pausen> alle = pausenDao.findByAtag(pause.getArbeitstag().getId());
		for (Pausen p : alle) {
			assertEquals(pause.getArbeitstag().getId(), p.getArbeitstag()
					.getId());
		}
		this.destroyPause();
	}

	@Test
	public void testFindCron() {
		Log.info("UnitTest - Pausen - FindCron");
		this.makePause(true);
		Calendar calendar = new GregorianCalendar();
		calendar.set(Calendar.DATE, 9);
		calendar.set(Calendar.MONTH, 9);
		calendar.set(Calendar.YEAR, 2012);
		calendar.set(Calendar.HOUR_OF_DAY, 18);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		Date datumCron = calendar.getTime();
		calendar.add(Calendar.DATE, 1);
		List<Pausen> cron = pausenDao.findCron(calendar.getTime());
		for (Pausen p : cron) {
			assertEquals(datumCron, p.getArbeitstag().getAtag_datum());
			assertEquals(null, p.getPause_stop());
		}
		this.destroyPause();
	}

	@Test
	public void testFindBySpan() {
		Log.info("UnitTest - Pausen - FindBySpan");
		Pausen pause = this.makePause(false);
		Calendar calendar = new GregorianCalendar();
		calendar.set(Calendar.DATE, 9);
		calendar.set(Calendar.MONTH, 9);
		calendar.set(Calendar.YEAR, 2012);
		calendar.set(Calendar.HOUR_OF_DAY, 10);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		Date start = calendar.getTime();
		calendar.add(Calendar.HOUR_OF_DAY, 5);
		Date end = calendar.getTime();
		List<Pausen> alle = pausenDao.findBySpan(start, end, pause
				.getArbeitstag().getId());
		for (Pausen p : alle) {
			assertTrue(this.getDifference(p.getPause_start(), start) >= 0);
			assertTrue(this.getDifference(p.getPause_stop(), end) <= 0);
		}
	}

	@SuppressWarnings("deprecation")
	private Pausen makePause(boolean flag) {
		String[] tables = { "pausen" };
		String[] tatag = { "arbeitstag" };
		String[] tmitarbeiter = { "mitarbeiter" };
		String[] tbasis = { "basis" };
		deleteFromTables(tables);
		deleteFromTables(tatag);
		deleteFromTables(tmitarbeiter);
		deleteFromTables(tbasis);
		Basis basis = new Basis();
		basis.setBasis_bez("test");
		basisDao.save(basis);
		Mitarbeiter mitarbeiter = new Mitarbeiter();
		mitarbeiter.setMit_name("Mustermann");
		mitarbeiter.setMit_vorname("Max");
		mitarbeiter.setMit_login("mm");
		mitarbeiter.setMit_pw("123");
		mitarbeiter.setMit_isadmin(true);
		mitarbeiterDao.save(mitarbeiter, basis.getId());
		Arbeitstag arbeitstag = new Arbeitstag();
		Calendar calendar = new GregorianCalendar();
		calendar.set(Calendar.DATE, 9);
		calendar.set(Calendar.MONTH, 9);
		calendar.set(Calendar.YEAR, 2012);
		calendar.set(Calendar.HOUR_OF_DAY, 9);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		arbeitstag.setAtag_von(calendar.getTime());
		calendar.add(Calendar.HOUR_OF_DAY, 9);
		arbeitstag.setAtag_bis(calendar.getTime());
		arbeitstag.setAtag_datum(calendar.getTime());
		arbeitstag.setMitarbeiter(mitarbeiter);
		arbeitstagDao.save(arbeitstag);
		calendar.set(Calendar.HOUR_OF_DAY, 12);
		Pausen pause = new Pausen();
		pause.setPause_start(calendar.getTime());
		calendar.add(Calendar.HOUR_OF_DAY, 1);
		if (!flag)
			pause.setPause_stop(calendar.getTime());
		pause.setArbeitstag(arbeitstag);
		pausenDao.save(pause);
		return pause;
	}

	@SuppressWarnings("deprecation")
	private void destroyPause() {
		String[] tables = { "pausen" };
		String[] tatag = { "arbeitstag" };
		String[] tmitarbeiter = { "mitarbeiter" };
		String[] tbasis = { "basis" };
		deleteFromTables(tables);
		deleteFromTables(tatag);
		deleteFromTables(tmitarbeiter);
		deleteFromTables(tbasis);
	}

	private float getDifference(Date d1, Date d2) {
		return (d1.getTime() - d2.getTime()) / 3600000;
	}
}
